<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>人脸识别系统</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.3.1/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .camera-container {
            width: 640px;
            height: 480px;
            margin: 20px auto;
            position: relative;
            border: 2px solid #ccc;
            overflow: hidden;
        }
        #video {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        #canvas {
            display: none;
        }
        .capture-btn {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 100;
        }
        .preview-container {
            width: 320px;
            height: 240px;
            margin: 20px auto;
            border: 1px solid #ddd;
            position: relative;
            overflow: hidden;
        }
        #preview {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        .loading-overlay {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 9999;
            justify-content: center;
            align-items: center;
        }
        .loading-spinner {
            width: 50px;
            height: 50px;
            border: 5px solid #f3f3f3;
            border-top: 5px solid #3498db;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="container mt-5">
        <h1 class="text-center mb-4">人脸识别系统</h1>
        
        <div class="row justify-content-center mb-4">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">选择识别方式</h5>
                        <div class="btn-group w-100" role="group">
                            <button type="button" class="btn btn-outline-primary" id="uploadBtn">上传图片</button>
                            <button type="button" class="btn btn-outline-primary" id="cameraBtn">使用摄像头</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 上传图片区域 -->
        <div id="uploadSection" class="row justify-content-center mb-4" style="display: none;">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">上传图片</h5>
                        <input type="file" class="form-control" id="imageInput" accept="image/*">
                        <div class="preview-container mt-3">
                            <img id="preview" src="#" alt="预览" style="display: none;">
                        </div>
                        <button class="btn btn-primary w-100 mt-3" id="uploadRecognizeBtn">开始识别</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 摄像头区域 -->
        <div id="cameraSection" class="row justify-content-center mb-4" style="display: none;">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">摄像头捕获</h5>
                        <div class="camera-container">
                            <video id="video" autoplay playsinline></video>
                            <canvas id="canvas"></canvas>
                            <button class="btn btn-primary capture-btn" id="captureBtn">拍照识别</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 加载框 -->
    <div class="loading-overlay" id="loadingOverlay">
        <div class="loading-spinner"></div>
    </div>

    <!-- 结果模态框 -->
    <div class="modal fade" id="resultModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">识别结果</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div id="resultMessage"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.3.1/js/bootstrap.bundle.min.js"></script>
    <script>
        // DOM 元素
        const uploadSection = document.getElementById('uploadSection');
        const cameraSection = document.getElementById('cameraSection');
        const uploadBtn = document.getElementById('uploadBtn');
        const cameraBtn = document.getElementById('cameraBtn');
        const imageInput = document.getElementById('imageInput');
        const preview = document.getElementById('preview');
        const video = document.getElementById('video');
        const canvas = document.getElementById('canvas');
        const captureBtn = document.getElementById('captureBtn');
        const uploadRecognizeBtn = document.getElementById('uploadRecognizeBtn');
        const resultModal = new bootstrap.Modal(document.getElementById('resultModal'));
        const resultMessage = document.getElementById('resultMessage');
        const loadingOverlay = document.getElementById('loadingOverlay');

        // 切换显示上传区域
        uploadBtn.addEventListener('click', () => {
            uploadSection.style.display = 'block';
            cameraSection.style.display = 'none';
        });

        // 切换显示摄像头区域
        cameraBtn.addEventListener('click', async () => {
            uploadSection.style.display = 'none';
            cameraSection.style.display = 'block';
            try {
                const stream = await navigator.mediaDevices.getUserMedia({ video: true });
                video.srcObject = stream;
            } catch (err) {
                alert('无法访问摄像头：' + err.message);
            }
        });

        // 预览上传的图片
        imageInput.addEventListener('change', function() {
            const file = this.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = function(e) {
                    preview.src = e.target.result;
                    preview.style.display = 'block';
                }
                reader.readAsDataURL(file);
            }
        });

        // 上传图片识别
        uploadRecognizeBtn.addEventListener('click', async () => {
            const file = imageInput.files[0];
            if (!file) {
                alert('请先选择图片');
                return;
            }

            const formData = new FormData();
            formData.append('image', file);

            // 显示加载框
            loadingOverlay.style.display = 'flex';

            try {
                const response = await fetch('http://localhost:3000/api/recognize', {
                    method: 'POST',
                    body: formData,
                    headers: {
                        'Accept': 'application/json'
                    },
                    mode: 'cors'
                });
                const result = await response.json();
                showResult(result);
            } catch (error) {
                showResult({ success: false, message: '识别失败：' + error.message });
            } finally {
                // 隐藏加载框
                loadingOverlay.style.display = 'none';
            }
        });

        // 拍照识别
        captureBtn.addEventListener('click', async () => {
            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;
            canvas.getContext('2d').drawImage(video, 0, 0);

            // 将 Canvas 数据转换为 Blob
            canvas.toBlob(async (blob) => {
                const formData = new FormData();
                formData.append('image', blob, 'capture.jpg');

                // 显示加载框
                loadingOverlay.style.display = 'flex';

                try {
                    const response = await fetch('/api/recognize', {
                        method: 'POST',
                        body: formData
                    });
                    const result = await response.json();
                    showResult(result);
                } catch (error) {
                    showResult({ success: false, message: '识别失败：' + error.message });
                } finally {
                    // 隐藏加载框
                    loadingOverlay.style.display = 'none';
                }
            }, 'image/jpeg');
        });

        // 显示识别结果
        function showResult(result) {
            if (result.success) {
                if (result.match && !result.match.isUnknown) {
                    resultMessage.innerHTML = `
                        <div class="alert alert-success">
                            <h4>识别成功！</h4>
                            <p>用户名：${result.match.label}</p>
                            <p>匹配度：${((1 - result.match.distance) * 100).toFixed(2)}%</p>
                        </div>
                    `;
                } else {
                    resultMessage.innerHTML = `
                        <div class="alert alert-warning">
                            <h4>未找到匹配用户</h4>
                            <p>该人脸未在系统中注册</p>
                        </div>
                    `;
                }
            } else {
                resultMessage.innerHTML = `
                    <div class="alert alert-danger">
                        <h4>识别失败</h4>
                        <p>${result.message}</p>
                    </div>
                `;
            }
            resultModal.show();
        }
    </script>
</body>
</html>